#ifndef _BROKERIMPL_H_
#define _BROKERIMPL_H_

#include "stdafx.h"
#include "node.h"

class CBrokerImpl : public IBroker, public IOperationProc, public IAcceptListen, public ITimerProc, public CUnknownImp

{
public:
    CBrokerImpl(void);
    virtual ~CBrokerImpl(void);

    BEGIN_STDCOM_MAP
    STDCOM_INTERFACE_ENTRY_UNKNOWN_(IBroker)
    STDCOM_INTERFACE_ENTRY(IOperationProc)
    STDCOM_INTERFACE_ENTRY(IAcceptListen)
    STDCOM_INTERFACE_ENTRY(ITimerProc)
    STDCOM_INTERFACE_ENTRY(IBroker)
    END_STDCOM_MAP

public:
    // IBroker
    std_method(Listen)(LPCSTR addr, size_t len, int maxconn);
    std_method(Dispatch)(unsigned int sec);
    std_method(Close)();
    std_method(IsListen)();

    // IAcceptListen
    std_method(Accept)(_sock_t s, SOCKADDR_PTR sa, socklen_t sl, crterr error_code);

    // IOperationProc
    std_method(OnComplete)(IBase* pOperation, crtid cid, crterr err);

    // ITimerProcs
    std_method(OnTimer)(crtid cid, crterr err);

public:
    HRESULT CreateSChannel(IBase* pRot);
    HRESULT OpenCChannel();
    HRESULT CloseChannel();
    HRESULT BindEvent(IBase* pBase) { return m_pIListen->BindAccept(pBase); }
    HRESULT UnBindEvent() { return m_pIListen->UnBindAccpet(); }
    HRESULT IsListenChannel() { return m_pIListen->IsOpen(); }

private:
    std_method(OnAccepted)(IBase* pBase, _sock_t s);
    std_method(OnRecvSeqed)(IBase* pIBase);
    std_method(OnSendSeqAcked)(IBase* pIBase);
    std_method(OnRecvAcked)(IBase* pIBase);

private:
    std_method(Init)();
    std_method(UnInit)();
    std_method(PushQueue)(IBase* pBase);

protected:
    _lComPtr<IRot> m_pRot;
    _lComPtr<IAsynFrame> m_pIAsynFrame;
    _lComPtr<ITcpSslListen> m_pIListen;

private:
    CLockQueue<Node*> m_AcceptQueue;
    CLockQueue<Node*> m_ConnectQueue;
    CLockQueue<Node*> m_Consumer;
    CLockQueue<Node*> m_Producer;

    UINT m_MaxConn;

    CSemHandle m_sem;
    CAutoLock m_lock;

private:
    // TimerPtr				m_ConnectTimer;
    // TimerPtr				m_HeartTimer;
};

#endif
